<?php

declare(strict_types=1);

namespace App\Middlewares;

use App\Helpers\CSRF;
use Riverside\Express\Request;
use Riverside\Express\Response;

/**
 * Protege rutas contra ataques CSRF.
 */
class CsrfMiddleware
{
    /**
     * Protege una petición con el token.
     */
    public function protect(Request $req, Response $res): void
    {
        $token = $req->session[CSRF::getSessionVarname()] ?? null;

        if (empty($token)) {
            // Genera el token.
            $token = CSRF::generateToken($req->path);

            $req->session[CSRF::getSessionVarname()] = $token;
        }

        // Se pasa el token en los controladores de la aplicación.
        $req->app->local(CSRF::getVarname(), $token);
    }

    /**
     * Comprueba el token de una petición.
     */
    public function verify(Request $req, Response $res): void
    {
        // Obtiene el token generado por la aplicación.
        $token = $req->session[CSRF::getSessionVarname()] ?? null;

        // Obtiene el token  de la petición.
        $test = $req->body[CSRF::getVarname()] ?? null;

        // Comprueba la autenticación del token.
        if (empty($token) || empty($test) || ! CSRF::verify($token, $test)) {
            $res->sendStatus(403);
        }
    }
}
